package com.situ.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.situ.mall.pojo.entity.product.Category;
import com.situ.mall.pojo.entity.product.Product;
import com.situ.mall.product.mapper.CategoryMapper;
import com.situ.mall.product.mapper.ProductMapper;
import com.situ.mall.product.pojo.vo.CategoryVO;
import com.situ.mall.product.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author CKX
 * @since 2024-10-10
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ProductMapper productMapper;

    //@Cacheable(value = {"category", "product"})
    //@Cacheable(value = "category", key = "'selectCategoryTree'")
    //@Cacheable(value = "category", key = "#root.methodName")
    //@Override
    public List<CategoryVO> selectCategoryTree1() {
        System.out.println("CategoryServiceImpl.selectCategoryTree");
        //1.查找所有分类，返回list集合
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("order_num");
        List<Category> categoryList = categoryMapper.selectList(queryWrapper);

        List<CategoryVO> categoryVOList = new ArrayList<>();
        categoryList.forEach(category -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category, categoryVO);
            categoryVOList.add(categoryVO);
        });

        //2.遍历所有的分类，通过parent_id=0得到所有的一级分类
        List<CategoryVO> oneCategoryVOList =
                categoryVOList.stream()
                        .filter(categoryVO -> categoryVO.getParentId().longValue() == 0)
                        .collect(Collectors.toList());

        //3.遍历所有的一级分类，id == parentId，得到一级分类下所有的二级分类
        oneCategoryVOList.forEach(oneCategoryVO -> {
            List<CategoryVO> twoCategoryVOList =
                    categoryVOList.stream()
                            .filter(category -> category.getParentId().longValue() == oneCategoryVO.getId())
                            .collect(Collectors.toList());
            //把二级分类放到一级分类的children里
            oneCategoryVO.setChildren(twoCategoryVOList);

            twoCategoryVOList.forEach(twoCategoryVO -> {
                List<CategoryVO> threeCategoryList =
                        categoryVOList.stream()
                                .filter(category -> category.getParentId().longValue() == twoCategoryVO.getId())
                                .collect(Collectors.toList());
                //把三级分类放到二级分类的children里
                twoCategoryVO.setChildren(threeCategoryList);
            });
        });

        return oneCategoryVOList;
    }

    @Cacheable(value = "category", key = "#root.methodName")
    @Override
    public List<CategoryVO> selectCategoryTree() {
        System.out.println("CategoryServiceImpl.selectCategoryTree");

        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("order_num");
        List<Category> categoryList = categoryMapper.selectList(queryWrapper);

        List<CategoryVO> categoryVOList = new ArrayList<>();
        categoryList.forEach(category -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category, categoryVO);
            categoryVOList.add(categoryVO);
        });

        List<CategoryVO> categoryVOTree = buildTree(categoryVOList);
        return categoryVOTree;
    }

    private List<CategoryVO> buildTree(List<CategoryVO> categoryVOList) {
        List<CategoryVO> treeList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categoryVOList)) {
            for (CategoryVO categoryVO : categoryVOList) {
                //递归的入口是parentId=0
                if (categoryVO.getParentId() == 0) {
                    categoryVO.setChildren(buildChildTree(categoryVO, categoryVOList));
                    treeList.add(categoryVO);
                }
            }
        }
        return treeList;
    }

    /**
     * @param categoryVO 要查找的childTree的父亲
     * @param categoryVOList 所有分类的集合
     * @return
     */
    private List<CategoryVO> buildChildTree(CategoryVO categoryVO, List<CategoryVO> categoryVOList) {
        List<CategoryVO> childTree = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categoryVOList)) {
            for (CategoryVO category : categoryVOList) {
                if (category.getParentId().longValue() == categoryVO.getId()) {
                    //添加孩子的时候，首先吧这个孩子的孩子的集合构造出来
                    category.setChildren(buildChildTree(category, categoryVOList));
                    childTree.add(category);
                }
            }
        }
        return childTree;
    }

    @Cacheable(value = "category", key = "{#root.methodName, #id}")
    @Override
    public List<CategoryVO> selectByParentId(Long id) {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        queryWrapper.orderByAsc("order_num");
        List<Category> categoryList = categoryMapper.selectList(queryWrapper);

        List<CategoryVO> categoryVOList = new ArrayList<>();
        categoryList.forEach(category -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category, categoryVO);
            //查找当前category是否有孩子
            QueryWrapper<Category> countQueryWrapper = new QueryWrapper<>();
            countQueryWrapper.eq("parent_id", categoryVO.getId());
            Long count = categoryMapper.selectCount(countQueryWrapper);
            if (count > 0) {
                categoryVO.setHasChildren(true);
            } else {
                categoryVO.setHasChildren(false);
            }
            categoryVOList.add(categoryVO);
        });
        return categoryVOList;
    }

    @Cacheable(value = "category", key = "{#root.methodName, #id}")
    @Override
    public List<Category> selectAllCategory3() {
        List<Category> list = new ArrayList<>();
        List<Product> productList = productMapper.selectAllCategory3();
        productList.forEach(product -> {
            Category category = categoryMapper.selectById(product.getCategory3Id());
            list.add(category);
        });
        return list;
    }

    /*@CacheEvict(value = "category", key = "'selectCategoryTree'")
    @Caching(evict = {
            @CacheEvict(value = "category", key = "'selectCategoryTree'"),
            @CacheEvict(value = "category", key = "'selectByParentId'")
    })*/
    @CacheEvict(value = "category", allEntries = true)
    @Override
    public void update(Category category) {
        categoryMapper.updateById(category);
    }

    @CacheEvict(value = "category", allEntries = true)
    @Override
    public void deleteById(Integer id) {
        categoryMapper.deleteById(id);
    }

    @CacheEvict(value = "category", allEntries = true)
    @Override
    public void add(Category category) {
        categoryMapper.insert(category);
    }
}
